# !encoding=utf-8

import sys
import socket
import time
import json
from GPIO import GPIO, PWM
from socketserver import DatagramRequestHandler
import socketserver


class SteerService(DatagramRequestHandler):
    STEER_FREQ = 50  # 50HZ
    trig = None
    echo = None
    steer = None
    delta = 0
    turned_angle = 0

    @classmethod
    def set_trig(cls, idx):
        SteerService.trig = GPIO(idx, init_with_output=True, init_with_high=False)

    @classmethod
    def set_echo(cls, idx):
        SteerService.echo = GPIO(idx, init_with_output=False)

    @classmethod
    def set_pwm(cls, idx):
        SteerService.steer = PWM(idx, SteerService.STEER_FREQ)

    @classmethod
    def set_delta(cls, delta):
        SteerService.delta = delta

    @classmethod
    def angle2frequency(cls, alpha):
        alpha += SteerService.delta
        if alpha < 0:
            alpha = 0
        alpha %= 180
        return round(alpha / 18. + 2.5)

    @classmethod
    def turn_angle(cls, alpha):
        SteerService.steer.chanage_duty_cycle(SteerService.angle2frequency(alpha))

    def handle(self):
        data = self.rfile.read()
        req_json = json.loads(data)
        action = req_json.get("action", None)
        if action is not None:
            if action == "turn-left-steer":
                SteerService.turned_angle += 15
            elif action == "turn-right-steer":
                SteerService.turned_angle -= 15
            if SteerService.turned_angle > 180:
                SteerService.turned_angle = 180
            elif SteerService.turned_angle < 0:
                SteerService.turned_angle = 0
            SteerService.turn_angle(SteerService.turned_angle)

    @classmethod
    def run(cls, port):
        server = socketserver.ThreadingUDPServer(('127.0.0.1', port), SteerService)
        server.serve_forever()


def main(port):
    SteerService.set_pwm(18)
    SteerService.set_echo(19)
    SteerService.set_trig(26)
    SteerService.run(port)


if __name__ == "__main__":
    main(int(sys.argv[1]))
